# coding: utf-8

import json
import time
from datetime import datetime
import os

from flask import (
    flash, render_template, redirect, url_for, request,
    send_file, abort
)
from flask_login import login_required, current_user
import xlwt

from app.extensions import db
from app.enterprise.forms import (
    EnterpriseForm, EnterpriseSearchForm, EnterpriseHomepageForm,
    EnterpriseProductForm, EnterpriseProjectForm,
    EnterpriseSecurityForm, EnterpriseHonourForm,
    EnterprisePictureForm, EnterpriseMediaReportForm,
    DispatchRuleForm
)
from app.enterprise.models import (
    Enterprise, SubAccountLog, enterprise_to_area, EnterpriseHomepage,
    EnterpriseProduct, EnterpriseProject, EnterpriseSecurity,
    EnterpriseHonour, EnterprisePicture, EnterpriseMediaReport
)
from app.enterprise import enterprise_bp
from app.enterprise.constant import EnterpriseLevel, OperatorType
from app.op.constant import AreaType
from app.op.models import (
    Area, User, Partic, Demand
)
from app.axb.models import NumberPoolForLT
from common.constant import ColorRule, SpanRule, SizeOperator
from common.models import ParticStatus
from app import encrypt

# 企业扩展信息使用动态的方式实现，这几个常量定义了映射关系
FORM_MAP = {
    'product': EnterpriseProductForm,
    'project': EnterpriseProjectForm,
    'security': EnterpriseSecurityForm,
    'honour': EnterpriseHonourForm,
    'picture': EnterprisePictureForm,
    'media_report': EnterpriseMediaReportForm,
}

MODEL_MAP = {
    'product': EnterpriseProduct,
    'project': EnterpriseProject,
    'security': EnterpriseSecurity,
    'honour': EnterpriseHonour,
    'picture': EnterprisePicture,
    'media_report': EnterpriseMediaReport,
}

ADD_TEMPLATE_MAP = {
    'product': 'enterprise_product/enterprise_product_add.html',
    'project': 'enterprise_project_add.html',
    'security': 'enterprise_security/enterprise_security_add.html',
    'honour': 'enterprise_honour/enterprise_honour_add.html',
    'picture': 'enterprise_picture/enterprise_picture_add.html',
    'media_report': 'enterprise_media_report_add.html',
}

EDIT_TEMPLATE_MAP = {
    'product': 'enterprise_product/enterprise_product_edit.html',
    'project': 'enterprise_project_edit.html',
    'security': 'enterprise_security/enterprise_security_edit.html',
    'honour': 'enterprise_honour/enterprise_honour_edit.html',
    'picture': 'enterprise_picture/enterprise_picture_edit.html',
    'media_report': 'enterprise_media_report_edit.html',
}


@enterprise_bp.route('/enterprise_add', methods=['GET', 'POST'])
@login_required
def add_enterprise():
    """
    create by ld_wu 2018-05-09
    新增企业账号
    """
    form = EnterpriseForm()

    z_tree_data = json.dumps(Area.make_prov_city_tree(
        active_city_ids=form.area_ids.data or list()
    ))

    def add_response():
        return render_template(
            'enterprise_add.html',
            form=form,
            level=EnterpriseLevel,
            z_tree_data=z_tree_data
        )

    if form.validate_on_submit():
        sub_account_ids = json.loads(form.sub_account.data)
        # 子账号加入企业主信息
        sub_account_ids.append(form.user_id.data)

        users = User.query.filter(
            User.id.in_(sub_account_ids)
        ).all()

        for user in users:
            if user.enterprises.first():
                flash('用户：{}已经加入了其他企业账号'.format(user.mobile))
                return add_response()

        if len(users) > form.account_limit.data:
            flash('企业子账号超过限制')
            return add_response()

        new_enterprise = Enterprise()
        form.populate_obj(new_enterprise)
        db.session.add(new_enterprise)
        db.session.flush()

        # 设置关注地区
        if form.area_ids.data:
            areas = Area.query.filter(
                Area.id.in_(form.area_ids.data),
                Area.type == AreaType.CITY.value
            ).all()
            if areas:
                new_enterprise.enterprise_areas = areas

        new_enterprise.sub_accounts = users

        for user in users:
            SubAccountLog.create(
                operator_type=OperatorType.PUSH.value,
                enterprise_id=new_enterprise.id,
                user_id=user.id,
                operator_id=current_user.id,
                operator_name=current_user.nickname
            )

        flash('新增成功')
        return redirect(url_for('enterprise_bp.enterprise_list'))
    else:
        if form.errors:
            print(form.errors)
            flash('表单数据有误，请检查')

    return add_response()


@enterprise_bp.route('/enterprises', methods=['GET', 'POST'])
@login_required
def enterprise_list():
    """
    create by ld_wu 2018-05-09
    企业账号列表
    :return:
    """
    search_form = EnterpriseSearchForm(formdata=request.form or request.args)

    search_args = {
        key: value for key, value in search_form.data.items() if value
    }
    query = Enterprise.generate_list_query_condition(search_args)

    if search_form.validate_on_submit():
        if search_form.mobile.data:
            user = User.get_by_args(mobile=search_form.mobile.data)
            if user:
                query = query.filter(
                    Enterprise.id == user.enterprise_info
                )
            else:
                query = query.filter(
                    Enterprise.id == 0
                )

        if search_form.prov.data and search_form.prov.data != -1:
            query = query.filter(
                Enterprise.id.in_(
                    db.session.query(enterprise_to_area).filter(
                        enterprise_to_area.c.area_id.like('{}%'.format(
                            str(search_form.prov.data)[:2]
                        ))
                    ).with_entities(
                        enterprise_to_area.c.enterprise_id
                    )
                )
            )

    pagination = query.paginate(error_out=False)
    enterprises = pagination.items
    return render_template(
        'enterprise_list.html',
        search_form=search_form,
        enterprises=enterprises,
        pagination=pagination,
        url_kwargs=search_args
    )


@enterprise_bp.route('/enterprises/<int:enterprise_id>', methods=['GET', 'POST'])
@login_required
def edit_enterprise(enterprise_id):
    """
    create by ld_wu 2018-05-14
    企业账号编辑
    """

    def redirect_to_url():
        return redirect(
            url_for(
                'enterprise_bp.edit_enterprise',
                enterprise_id=enterprise_id
            )
        )

    enterprise = Enterprise.query.get_or_404(enterprise_id)

    enterprise_areas = enterprise.enterprise_areas
    area_ids = [area.id for area in enterprise_areas]

    if request.method == 'POST':
        form = EnterpriseForm()

        if form.validate_on_submit():
            sub_account_ids = json.loads(form.sub_account.data)
            # 子账号加入企业主信息
            sub_account_ids.append(form.user_id.data)
            users = User.query.filter(
                User.id.in_(sub_account_ids)
            ).all()

            for user in users:
                user_enterprise = user.enterprises.first()
                if user_enterprise:
                    if user_enterprise.id != enterprise_id:
                        flash('用户：{}已经加入了其他企业账号'.format(user.mobile))
                        return redirect_to_url()

            if len(users) > form.account_limit.data:
                flash('企业子账号超过限制')
                return redirect_to_url()

            # 设置关注地区
            if form.area_ids.data:
                areas = Area.query.filter(
                    Area.id.in_(form.area_ids.data),
                    Area.type == AreaType.CITY.value
                ).all()
                if areas:
                    enterprise.enterprise_areas = areas

            enterprise.sub_accounts = users

            form.populate_obj(enterprise)
            db.session.add(enterprise)
            db.session.flush()
            flash('更新企业账号成功')
            return redirect(url_for('enterprise_bp.enterprise_list'))
        else:
            flash('编辑出错，请检查表单数据。')
            return redirect(
                url_for(
                    'enterprise_bp.edit_enterprise',
                    enterprise_id=enterprise_id
                )
            )
    else:
        form = EnterpriseForm(obj=enterprise)

        z_tree_data = json.dumps(Area.make_prov_city_tree(
            active_city_ids=form.area_ids.data or area_ids
        ))
        user = enterprise.user
        form.user_id.data = user.id
        form.mobile.data = user.mobile
        form.name.data = user.nickname

        sub_accounts = [
            account for account in enterprise.sub_accounts
            if account.id != enterprise.user_id
        ]

        return render_template(
            'enterprise_info.html',
            form=form,
            enterprise_id=enterprise_id,
            level=EnterpriseLevel,
            z_tree_data=z_tree_data,
            sub_accounts=sub_accounts
        )


@enterprise_bp.route(
    '/enterprise_homepage_edit/<int:enterprise_id>', methods=['GET', 'POST'])
@login_required
def enterprise_homepage_edit(enterprise_id):
    """
    create by lina 2018-05-23
    企业号首页信息管理页面
    """
    Enterprise.query.get_or_404(enterprise_id)
    form = EnterpriseHomepageForm()
    enterprise_homepage = EnterpriseHomepage.get_by_args(
        enterprise_id=enterprise_id
    )
    if not enterprise_homepage:
        enterprise_homepage = EnterpriseHomepage.create(
            enterprise_id=enterprise_id
        )

    if form.validate_on_submit():
        # 企业虚拟号相关操作
        err_msg = NumberPoolForLT.bind_for_enterprise(
            enterprise_id, form.virtual_number.data)
        if err_msg:
            flash('虚拟号出错!{err_msg}'.format(err_msg=err_msg))
            return render_template(
                'enterprise_homepage_edit.html',
                form=form,
                enterprise_id=enterprise_id,
                enterprise_homepage=enterprise_homepage,
            )

        # 首页基本信息更新
        form.populate_obj(enterprise_homepage)

        flash('修改成功')
        return redirect(url_for('enterprise_bp.enterprise_list'))

    form = EnterpriseHomepageForm(obj=enterprise_homepage)

    return render_template(
        'enterprise_homepage_edit.html',
        form=form,
        enterprise_id=enterprise_id,
        enterprise_homepage=enterprise_homepage,
    )


@enterprise_bp.route(
    '/enterprise_homepage_extend_edit/<int:enterprise_id>',
    methods=['GET', 'POST']
)
@login_required
def enterprise_homepage_extend_edit(enterprise_id):
    """
    add by zhouhl 2018-05-30
    企业号首页扩展信息编辑
    """
    Enterprise.query.get_or_404(enterprise_id)
    enterprise_homepage = EnterpriseHomepage.get_by_args(
        enterprise_id=enterprise_id
    )
    # 保障体系
    enterprise_securities = enterprise_homepage.enterprise.securities
    # 产品信息
    enterprise_products = enterprise_homepage.enterprise.products
    # 荣誉资质
    enterprise_honours = enterprise_homepage.enterprise.honours
    # 公司图片
    enterprise_pictures = enterprise_homepage.enterprise.pictures
    # 企业项目类型
    enterprise_projects = enterprise_homepage.enterprise.projects
    # 新闻媒体报道
    enterprise_media_reports = enterprise_homepage.enterprise.media_reports
    # 企业派单规则
    enterprise_dispatch_rules = ''
    if enterprise_homepage.enterprise.dispatch_rule:
        dispatch_rule = enterprise_homepage.enterprise.dispatch_rule
        enterprise_dispatch_rules = json.loads(dispatch_rule)
        for enterprise_dispatch_rule in enterprise_dispatch_rules:
            enterprise_dispatch_rule['color'] = ColorRule(
                enterprise_dispatch_rule['color']
            ).display if enterprise_dispatch_rule['color'] else '全部'

            enterprise_dispatch_rule['span'] = SpanRule(
                enterprise_dispatch_rule['span']
            ).display if enterprise_dispatch_rule['span'] else '全部'

            enterprise_dispatch_rule['size_op'] = SizeOperator(
                enterprise_dispatch_rule['size_op']
            ).display if enterprise_dispatch_rule['size_op'] else '全部'

    return render_template(
        'enterprise_homepage_extend_edit.html',
        enterprise_id=enterprise_id,
        enterprise_homepage=enterprise_homepage,
        enterprise_products=enterprise_products,
        enterprise_securities=enterprise_securities,
        enterprise_honours=enterprise_honours,
        enterprise_pictures=enterprise_pictures,
        enterprise_projects=enterprise_projects,
        enterprise_media_reports=enterprise_media_reports,
        enterprise_dispatch_rules=enterprise_dispatch_rules,
    )


@enterprise_bp.route(
    '/enterprise/add/<item_key>/<int:enterprise_id>', methods=['GET', 'POST'])
@login_required
def enterprise_item_add(item_key, enterprise_id):
    """
    add by zhouhl 2018-05-25
    新增企业扩展信息
    """
    if item_key not in list(MODEL_MAP.keys()):
        flash('无效的item_key，请联系管理员')
        return redirect(url_for(
            'enterprise_bp.enterprise_homepage_edit',
            enterprise_id=enterprise_id
        ))

    form = FORM_MAP[item_key]()
    if form.validate_on_submit():
        new_item = MODEL_MAP[item_key](enterprise_id=enterprise_id)
        form.populate_obj(new_item)
        db.session.add(new_item)
        flash('新增成功')
        return redirect(url_for(
            'enterprise_bp.enterprise_homepage_extend_edit',
            enterprise_id=enterprise_id
        ))
    else:
        if form.errors:
            flash('表单数据有误，请检查')

    template_path = ADD_TEMPLATE_MAP[item_key]
    return render_template(
        template_path,
        form=form,
        enterprise_id=enterprise_id,
    )


@enterprise_bp.route(
    '/enterprise/edit/<item_key>/<int:item_id>', methods=['GET', 'POST'])
@login_required
def enterprise_item_edit(item_key, item_id):
    """
    add by zhouhl 2018-05-25
    编辑企业扩展信息
    """
    if item_key not in list(MODEL_MAP.keys()):
        flash('无效的item_key，请联系管理员')
        return redirect(
            url_for('enterprise_bp.enterprise_list'))

    form = FORM_MAP[item_key]()

    enterprise_item = MODEL_MAP[item_key].query.get_or_404(item_id)
    if form.validate_on_submit():
        form.populate_obj(enterprise_item)
        flash('修改成功')
        return redirect(url_for(
            'enterprise_bp.enterprise_homepage_extend_edit',
            enterprise_id=enterprise_item.enterprise_id
        ))

    form = FORM_MAP[item_key](obj=enterprise_item)

    template_path = EDIT_TEMPLATE_MAP[item_key]
    return render_template(
        template_path,
        form=form,
        enterprise_item=enterprise_item,
    )


@enterprise_bp.route(
    '/enterprise/delete/<item_key>/<int:item_id>', methods=['GET'])
@login_required
def enterprise_item_delete(item_key, item_id):
    """
    add by zhouhl 2018-05-25
    删除企业扩展信息
    """
    if item_key not in list(MODEL_MAP.keys()):
        flash('无效的item_key，请联系管理员')
        return redirect(
            url_for('enterprise_bp.enterprise_list'))

    enterprise_item = MODEL_MAP[item_key].query.get_or_404(item_id)
    enterprise_id = enterprise_item.enterprise_id

    db.session.delete(enterprise_item)
    return redirect(url_for(
        'enterprise_bp.enterprise_homepage_extend_edit',
        enterprise_id=enterprise_id
    ))


@enterprise_bp.route(
    '/enterprise_dispatch_rule_add/<int:enterprise_id>', methods=['GET', 'POST'])
@login_required
def enterprise_dispatch_rule_add(enterprise_id):
    """
    add by lina 2018-8-18
     新增企业派单规则
    """
    form = DispatchRuleForm()
    res = {}
    rules = []
    enterprise = Enterprise.query.get_or_404(enterprise_id)
    if form.validate_on_submit():
        res['color'] = form.color.data if form.color.data != -1 else ''
        res['size'] = form.size.data if form.size.data else ''
        res['size_op'] = form.size_op.data if form.size_op.data != -1 else ''
        res['span'] = form.span.data if form.span.data != -1 else ''
        res['time_stamp'] = int(time.time())
        if enterprise.dispatch_rule:
            rules = json.loads(enterprise.dispatch_rule)
        rules.append(res)
        enterprise.dispatch_rule = json.dumps(rules)
        flash('新增派单规则成功')
        return redirect(
            url_for('enterprise_bp.enterprise_homepage_extend_edit',
                    enterprise_id=enterprise_id
                    ))

    return render_template(
        'enterprise_dispatch_rule_add.html',
        form=form,
        enterprise_id=enterprise_id
    )


@enterprise_bp.route(
    '/enterprise_dispatch_rule_edit/<int:enterprise_id>/<int:time_stamp>', methods=['GET', 'POST'])
@login_required
def enterprise_dispatch_rule_edit(enterprise_id, time_stamp):
    """
    add by lina 2018-08-18
    编辑企业派单规则
    """
    form = DispatchRuleForm()
    enterprise = Enterprise.query.get_or_404(enterprise_id)
    rules = json.loads(enterprise.dispatch_rule)
    if form.validate_on_submit():
        for j in rules:
            if time_stamp == j['time_stamp']:
                j['color'] = form.color.data if form.color.data != -1 else ''
                j['size'] = form.size.data if form.size.data else ''
                j['size_op'] = form.size_op.data if form.size_op.data != -1 else ''
                j['span'] = form.span.data if form.span.data != -1 else ''

        enterprise.dispatch_rule = json.dumps(rules)
        flash('修改成功')
        return redirect(url_for(
            'enterprise_bp.enterprise_homepage_extend_edit',
            enterprise_id=enterprise_id
        ))
    for j in rules:
        if time_stamp == j['time_stamp']:
            form.color.data = j['color']
            form.size.data = j['size']
            form.span.data = j['span']
            form.size_op.data = j['size_op']
            break
    return render_template(
        'enterprise_dispatch_rule_edit.html',
        form=form,
        enterprise_id=enterprise_id,
        time_stamp=time_stamp
    )


@enterprise_bp.route(
    '/enterprise_dispatch_rule/delete/<int:enterprise_id>/<int:time_stamp>', methods=['GET'])
@login_required
def enterprise_dispatch_rule_delete(enterprise_id, time_stamp):
    """
    add by lina 2018-08-18
    删除企业派单规则
    """
    enterprise = Enterprise.query.get_or_404(enterprise_id)
    rules = json.loads(enterprise.dispatch_rule)
    for i, j in enumerate(rules):
        if time_stamp == j['time_stamp']:
            del rules[i]
            break
    enterprise.dispatch_rule = json.dumps(rules)
    flash('删除成功')
    return redirect(url_for(
        'enterprise_bp.enterprise_homepage_extend_edit',
        enterprise_id=enterprise_id
    ))


@enterprise_bp.route('/export/enterprise_demand_list/<int:enterprise_id>')
@login_required
def export_enterprise_demand_list(enterprise_id):
    """
    add by lina 2018-08-23
    导出企业派单信息
    """
    template_path = '/tmp/enterprise_demand_list_{}.xls'.format(datetime.now())
    book = xlwt.Workbook('utf-8')
    fields = [
        '序号', '推送时间', '客户手机号', '客户称呼', '订单类型', '室内外', '面积', '颜色', '间距',
        '省份', '城市', '跟进状态', '跟进人', '项目ID'
    ]
    sheet = book.add_sheet('企业派单详情')
    for index, item in enumerate(fields):
        sheet.write(0, index, item)
    get_begin_time = request.args.get('begin_time')
    get_end_time = request.args.get('end_time')
    if not get_end_time:
        get_end_time = str(time.strftime('%Y-%m-%d',time.localtime(time.time())))
    enterprise = Enterprise.query.get_or_404(enterprise_id)
    if get_begin_time:
        begin_time = int(time.mktime(datetime.strptime(get_begin_time, '%Y-%m-%d').timetuple()))
        end_time = int(time.mktime(datetime.strptime(get_end_time, '%Y-%m-%d').timetuple()))
        demands_ids = Partic.query.filter(
            Partic.enterprise_id == enterprise.id,
            Partic.created_at.between(begin_time, end_time)
        ).with_entities(Partic.demand_id)
    else:
        demands_ids = Partic.query.filter(
            Partic.enterprise_id == enterprise.id,
        ).with_entities(Partic.demand_id)
    demand_query = Demand.query.filter(
        Demand.id.in_(demands_ids)
    )

    for index, item in enumerate(demand_query):
        sheet.write(index + 1, 0, index + 1)
        sheet.write(index + 1, 4, item.type_display)
        sheet.write(index + 1, 5, item.surr_display)
        sheet.write(index + 1, 6, item.size)
        sheet.write(index + 1, 7, item.color_display)
        sheet.write(index + 1, 8, item.span)
        sheet.write(index + 1, 9, item.prov)
        sheet.write(index + 1, 10, item.city)
        sheet.write(index + 1, 13, item.id)

        partic_query = Partic.query.filter(
            Partic.demand_id == item.id,
            Partic.enterprise_id == enterprise_id
        ).join(
            User,
            Partic.supplier_id == User.id
        ).with_entities(
            Partic.created_at,
            Partic.status,
            Partic.follow_msg,
            Partic.follow_type,
            Partic.is_revert,
            Partic.apply_real_number_state,
            User.nickname,
            User.mobile,
        ).order_by(
            Partic.status.desc()
        ).first()
        sheet.write(index + 1, 1, datetime.fromtimestamp(partic_query.created_at).strftime('%F'))
        client = User.query.filter(
            User.id == item.uid
        ).first()
        sheet.write(index + 1, 3, client.nickname)
        if partic_query.is_revert or partic_query.status != ParticStatus.SUCCEED.value:
            if enterprise.level in (EnterpriseLevel.LEVEL_4.value, EnterpriseLevel.LEVEL_5.value):
                sheet.write(index + 1, 2, client.mobile)
            else:
                sheet.write(index + 1, 2, encrypt(client.mobile))
            sheet.write(index + 1, 11, '/')
            sheet.write(index + 1, 12, '/')
        else:
            if partic_query.follow_type == 2:
                sheet.write(index + 1, 11, '已跟进')
            elif partic_query.follow_type == 1:
                sheet.write(index + 1, 11, '已跟进(锁定)')
            sheet.write(index + 1, 12, partic_query.nickname)
            sheet.write(index + 1, 2, client.mobile)
    book.save(template_path)
    if not os.path.exists(template_path):
        abort(404)
    return send_file(template_path, as_attachment=True)